package com.nidu.demo.mail.gatewayimpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.PageQuery;
import com.alibaba.cola.dto.PageResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nidu.demo.mail.convertor.MailLogConvertor;
import com.nidu.demo.mail.gateway.MailLogGateway;
import com.nidu.demo.mail.mapper.MailLogMapper;
import com.nidu.demo.mail.mapper.dataobject.MailLogDO;
import com.nidu.demo.mail.model.MailLog;
import com.nidu.demo.mail.model.MailLogCriteria;
import com.nidu.demo.user.mapper.dataobject.UserDO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 邮件日志网关实现
 *
 * @author auto
 */
@Component
@RequiredArgsConstructor
public class MailLogGatewayImpl implements MailLogGateway {

    private final MailLogMapper mapper;
    private final MailLogConvertor convertor;

    @Override
    public MailLog create(MailLog mailLog) {
        MailLogDO mailLogDO = convertor.toDataObject(mailLog);
        mapper.insert(mailLogDO);
        return convertor.toDomainObject(mailLogDO);
    }

    @Override
    public MailLog update(MailLog mailLog) {
        MailLogDO mailLogDO = convertor.toDataObject(mailLog);
        mapper.updateById(mailLogDO);
        return convertor.toDomainObject(mailLogDO);
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteById(id);
    }

    @Override
    public void deleteByIds(Set<Long> ids) {
        mapper.deleteByIds(ids);
    }

    @Override
    public MailLog getById(Long id) {
        MailLogDO mailLogDO = mapper.selectById(id);
        if (mailLogDO == null) {
            return null;
        }
        return convertor.toDomainObject(mailLogDO);
    }

    @Override
    public List<MailLog> getByIds(Set<Long> ids) {
        LambdaQueryWrapper<MailLogDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(MailLogDO::getId, ids);
        List<MailLogDO> mailLogDOS = mapper.selectList(wrapper);
        if (CollUtil.isEmpty(mailLogDOS)) {
            return new ArrayList<>();
        }
        return convertor.toDomainObjects(mailLogDOS);
    }

    @Override
    public List<MailLog> listByCondition(MailLogCriteria criteria) {
        LambdaQueryWrapper<MailLogDO> wrapper = buildQueryWrapper(criteria);
        List<MailLogDO> mailLogDOS = mapper.selectList(wrapper);
        if (CollUtil.isEmpty(mailLogDOS)) {
            return new ArrayList<>();
        }
        return convertor.toDomainObjects(mailLogDOS);
    }

    @Override
    public PageResponse<MailLog> pageByCondition(MailLogCriteria criteria) {
        // 创建查询条件
        LambdaQueryWrapper<MailLogDO> wrapper = buildQueryWrapper(criteria);

        // 创建分页对象
        Page<MailLogDO> page = new Page<>(criteria.getPageIndex(), criteria.getPageSize());

        // 排序字段
        if (!StrUtil.isEmpty(criteria.getOrderBy())) {
            if (PageQuery.DESC.equals(criteria.getOrderDirection())) {
                page.addOrder(OrderItem.desc(criteria.getOrderBy()));
            } else {
                page.addOrder(OrderItem.asc(criteria.getOrderBy()));
            }
        }

        // 执行分页查询
        mapper.selectPage(page, wrapper);
        List<MailLog> mailLogs = convertor.toDomainObjects(page.getRecords());
        return PageResponse.of(mailLogs, (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
    }

    @Override
    public void updateSendSuccess(Long id, Integer status, String messageId) {
        MailLogDO mailLogDO = new MailLogDO();
        mailLogDO.setId(id);
        mailLogDO.setSendStatus(status);
        mailLogDO.setSendMessageId(messageId);
        mapper.updateById(mailLogDO);
    }

    @Override
    public void updateSendFail(Long id, Integer status, String sendException) {
        MailLogDO mailLogDO = new MailLogDO();
        mailLogDO.setId(id);
        mailLogDO.setSendStatus(status);
        mailLogDO.setSendException(sendException);
        mapper.updateById(mailLogDO);
    }

    private LambdaQueryWrapper<MailLogDO> buildQueryWrapper(MailLogCriteria criteria) {
        LambdaQueryWrapper<MailLogDO> wrapper = new LambdaQueryWrapper<>();
        
        // 时间范围条件
        LocalDateTime[] createTime = criteria.getCreateTime();
        if (createTime != null) {
            if (createTime.length == 1 && createTime[0] != null) {
                wrapper.ge(MailLogDO::getCreateTime, createTime[0]);
            } else if (createTime.length > 1 && createTime[0] != null && createTime[1] != null) {
                wrapper.between(MailLogDO::getCreateTime, createTime[0], createTime[1]);
            }
        }
        
        // 发送时间范围条件
        LocalDateTime[] sendTime = criteria.getSendTime();
        if (sendTime != null) {
            if (sendTime.length == 1 && sendTime[0] != null) {
                wrapper.ge(MailLogDO::getSendTime, sendTime[0]);
            } else if (sendTime.length > 1 && sendTime[0] != null && sendTime[1] != null) {
                wrapper.between(MailLogDO::getSendTime, sendTime[0], sendTime[1]);
            }
        }
        
        // 精确查询条件
        wrapper.eq(criteria.getUserId() != null, MailLogDO::getUserId, criteria.getUserId());
        wrapper.eq(criteria.getAccountId() != null, MailLogDO::getAccountId, criteria.getAccountId());
        wrapper.eq(criteria.getTemplateId() != null, MailLogDO::getTemplateId, criteria.getTemplateId());
        wrapper.eq(criteria.getSendStatus() != null, MailLogDO::getSendStatus, criteria.getSendStatus());
        
        // 模糊查询条件
        wrapper.like(!StrUtil.isEmpty(criteria.getToMails()), MailLogDO::getToMails, criteria.getToMails());
        wrapper.like(!StrUtil.isEmpty(criteria.getTemplateCode()), MailLogDO::getTemplateCode, criteria.getTemplateCode());
        
        return wrapper;
    }

}
